'''
Algoritmo K-Means
1- Scegliere il numero di cluster k
2- inizializzare il codebook V con vettori presi casualmente da x
3- calcolare il voronoy set \pi_i associato al codevector \vec{v}_i 
4- spostare ogni codevector nel valor medio del suo voronoy set 
usando l'equazione 4: v_i = \frac{1}{|\pi_i|} \sum_{x \e \pi_i} x
5- ritornare allo step 3, se uno qualunque dei codevector e' cambiato
altrimenti ritornare il codebook. 

'''
import pylab as pl
import time
import copy 

from initialization.Start import *
from data.Centroids import *
import utility.graph as GR
	
def cluster():
	
	### acquisisco i parametri iniziali e leggo il file di dati.
	EACL = Start()
	
	### numero di dati acquisiti dal file
	nDat = EACL.get_fileLen()
	
	### insieme dei dati acquisiti
	X = EACL.get_scanFile()
	
	### istanzio i nuovi centroidi
	V = Centroids(EACL.nCentr,EACL.nDat,X)
	
	### stampo le coord dei centroidi iniziale
	V.printData()
	
	### calcolo il voronoi set iniziale
	V.voronoi(X)
	
	### calcolo la matrice di best mach iniziale
	V.bestMatch()
	#~ V.print_w()
	
	### associo i punti ai centroidi iniziali
	V.setCentroidToPoint(X)
	
	pl.figure(num=None, figsize=(12, 8), dpi=80, facecolor='g', edgecolor='y')
	
	### inizializza il grafico
	gr = V.initGraph(pl,X)
	
	### TODO:   agiungere algoritmo evolutivo
	while(1):
		### NOTA: questa sfilza di comandi potrebbe essere raggruppata
		
		### deep copy dei centroidi per la condizione di stop
		Vtocp = V.get_centroids()
		Vold = copy.deepcopy(Vtocp) 
		### aggiorno la posizione dei centroidi con il metodo k-mean
		V.updateCentroidsPosition(X)
			
		### calcolo il voronoi set
		V.voronoi(X)
		
		### calcolo la matrice di best mach
		V.bestMatch()
		#~ V.print_w()
		
		### associo i punti ai centroidi
		V.setCentroidToPoint(X)
		
		### DEBUG: stampo le coord dei centroidi
		print " "
		V.printData()
				
		V.updateGraph(pl,gr)
		time.sleep(.2)
		
		### verifica condizione di stop
		if(V.stop(Vold) == 1): 
			print "Clustering teminato !!"
			break
		
	### Alla fine i punti vengono ricolorati a seconda della loro
	### appartenenza ad un centroide
	
	GR.colorDivision(X,EACL.get_nCentr(),EACL.get_fileLen())
	
	### altrimenti si chiude il grafico
	
	pl.show()
		
def main():
	 
	 cluster()
	
if __name__ == "__main__":
	main()


